const http = require("http");
const url = require("url");
const path = require("path");
const fs = require("fs").promises;
const { createReadStream } = require("fs");
const mime = require("mime");
const ejs = require("ejs");
const { promisify } = require("util");

function mergeConfig(config) {
  return {
    port: 1234,
    directory: process.cwd(),
    ...config,
  };
}

class Server {
  constructor(config) {
    this.config = mergeConfig(config);
    console.log(this.config);
  }
  start() {
    let server = http.createServer(this.serverHandler.bind(this)); // 比较特殊哟
    server.listen(this.config.port, () => {
      console.log("服务已经启动了.....");
    });
  }

  async serverHandler(req, res) {
    let { pathname } = url.parse(req.url);
    pathname = decodeURIComponent(pathname); // 处理中文目录
    // console.log(pathname);
    let abspath = path.join(this.config.directory, pathname);
    console.log(abspath);
    try {
      let statObj = await fs.stat(abspath);
      if (statObj.isFile()) {
        this.fileHandler(req, res, abspath);
      } else {
        // 处理目录
        let dirs = await fs.readdir(abspath);
        dirs = dirs.map((item) => {
          return {
            path: path.join(pathname, item),
            dirs: item,
          };
        });
        // console.log(dirs);
        // promisify;
        let renderFile = promisify(ejs.renderFile);
        let parentPath = path.dirname(pathname);
        let ret = await renderFile(path.resolve(__dirname, "template.html"), {
          arr: dirs,
          parentpath: parentPath,
          parent: pathname == "/" ? false : true,
          title: path.basename(abspath),
        });
        res.end(ret);
      }
    } catch (error) {
      this.errorHandler(req, res, error);
    }
  }

  errorHandler(req, res, err) {
    console.log(err);
    res.statusCode = 404;
    res.setHeader("Content-type", "text/html;charset=utf-8");
    res.end("Not found");
  }

  fileHandler(req, res, abspath) {
    res.statusCode = 200;
    res.setHeader("Content-type", `${mime.getType(abspath)};charset=utf-8`);
    createReadStream(abspath).pipe(res);
  }
}

module.exports = Server;
